Spring JDBC-তে Query Methods ডেটাবেস থেকে ডেটা রিট্রিভ বা রিড করার জন্য ব্যবহৃত হয়। এগুলো JdbcTemplate ক্লাসের মাধ্যমে কাজ করে। বিভিন্ন ধরণের SQL কোয়েরি পরিচালনার জন্য Spring JDBC একাধিক পদ্ধতি (methods) প্রদান করে।
Spring JDBC Query Methods এর ধরন
queryForObject()
নির্দিষ্ট একটি রেকর্ড বা একটি মান রিটার্ন করে।ব্যবহার:
- যখন একটি নির্দিষ্ট রো বা কলাম রিটার্ন করতে হয়।
- ডেটা টাইপ সরাসরি ম্যাপ করার জন্য।
উদাহরণ:
String sql = "SELECT name FROM users WHERE id = ?"; String name = jdbcTemplate.queryForObject(sql, new Object[]{1}, String.class); System.out.println("User Name: " + name);এখানে
queryForObject()SQL কোয়েরি থেকে একটিStringমান রিটার্ন করবে।
queryForList()
ডেটাবেস থেকে রো-ভিত্তিক ডেটার একটি তালিকা (List) রিটার্ন করে।ব্যবহার:
- যখন একটি কলাম বা রেকর্ডের তালিকা রিটার্ন করতে হয়।
- সরাসরি
Listবা নির্দিষ্ট টাইপেরListপেতে।
উদাহরণ:
String sql = "SELECT name FROM users"; List<String> userNames = jdbcTemplate.queryForList(sql, String.class); userNames.forEach(System.out::println);এখানে
queryForList()সব ইউজারের নামের একটি তালিকা রিটার্ন করবে।
query()
জটিল বা কাস্টম রো-ম্যাপিং করার জন্য ব্যবহৃত হয়। এটি একটি RowMapper ফাংশন গ্রহণ করে, যা ডেটাকে অবজেক্টে রূপান্তর করে।ব্যবহার:
- যখন পুরো রেকর্ড বা জটিল ডেটা স্ট্রাকচার পেতে হয়।
উদাহরণ:
String sql = "SELECT * FROM users"; List<User> users = jdbcTemplate.query(sql, (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name"), rs.getString("email")) ); users.forEach(System.out::println);এখানে
query()একটি কাস্টম অবজেক্ট (User) এর তালিকা রিটার্ন করবে।
queryForMap()
একটি রোকে একটিMapএর মধ্যে রূপান্তর করে, যেখানে কলামের নাম হবে কী (key) এবং কলামের মান হবে ভ্যালু (value)।ব্যবহার:
- যখন একটি রেকর্ডকে কী-ভ্যালু পেয়ারে পেতে হয়।
উদাহরণ:
String sql = "SELECT * FROM users WHERE id = ?"; Map<String, Object> user = jdbcTemplate.queryForMap(sql, 1); System.out.println("User Data: " + user);এখানে
queryForMap()ইউজারের ডেটাকে একটিMapহিসেবে রিটার্ন করবে।
queryForRowSet()
এটি একটিSqlRowSetরিটার্ন করে, যা JDBC এর ResultSet-এর অনুরূপ। এটি ডেটাবেস থেকে ডেটা রিড করার সময় ব্যবহার করা হয়।ব্যবহার:
- যখন রিড-অনলি এবং ফরওয়ার্ড-অনলি ডেটা অ্যাক্সেস প্রয়োজন।
উদাহরণ:
String sql = "SELECT * FROM users"; SqlRowSet rowSet = jdbcTemplate.queryForRowSet(sql); while (rowSet.next()) { System.out.println("User Name: " + rowSet.getString("name")); }
queryForInt() এবং queryForLong() (ডিপ্রিকেটেড)
নির্দিষ্ট একটি সংখ্যামূলক ভ্যালু রিটার্ন করতে ব্যবহৃত হত। বর্তমানে এই পদ্ধতিগুলো ব্যবহার না করেqueryForObject()ব্যবহার করা হয়।উদাহরণ:
String sql = "SELECT COUNT(*) FROM users"; int userCount = jdbcTemplate.queryForObject(sql, Integer.class); System.out.println("Total Users: " + userCount);
Spring JDBC Query Methods এর সংক্ষিপ্ত তুলনা
| Method Name | Return Type | ব্যবহার | উদাহরণ |
|---|---|---|---|
queryForObject() | Single Object | একটি রেকর্ড বা কলাম রিটার্ন | একক ইউজারের নাম বা ID পেতে |
queryForList() | List of Objects | একাধিক রেকর্ড রিটার্ন | ইউজারদের নামের তালিকা পেতে |
query() | List of Objects | কাস্টম অবজেক্ট ম্যাপিং | User অবজেক্টের তালিকা |
queryForMap() | Map (Key-Value) | একটি রেকর্ড কী-ভ্যালু পেয়ারে পেতে | |
queryForRowSet() | SqlRowSet | ResultSet এর বিকল্প | ডেটার স্ট্রিম রিডিং |
উপসংহার
Spring JDBC-এর Query Methods ডেটাবেস থেকে ডেটা রিড করার সময় সরলতা ও কার্যকারিতা বৃদ্ধি করে। এই পদ্ধতিগুলো দিয়ে সহজ SQL কোয়েরি থেকে শুরু করে জটিল ডেটা ম্যাপিং পর্যন্ত করা যায়। ডেভেলপমেন্ট প্রক্রিয়া দ্রুত এবং কার্যকরী করতে Spring JDBC-এর এই Query Methods খুবই গুরুত্বপূর্ণ।
Spring JDBC-তে JdbcTemplate একটি অত্যন্ত গুরুত্বপূর্ণ ক্লাস যা ডাটাবেস অপারেশনগুলো সহজতর করে। এর মধ্যে queryForObject() এবং query() মেথড দুটি সাধারণ ডাটাবেস রিড অপারেশনের জন্য ব্যবহৃত হয়।
1. queryForObject()
queryForObject() মেথড ব্যবহার করা হয় যখন আমরা নিশ্চিত থাকি যে ডাটাবেস থেকে একটি সুনির্দিষ্ট একক রেকর্ড (single row) রিটার্ন হবে। এটি সাধারণত সিঙ্গেল কলাম বা একটি অবজেক্ট ম্যাপিং করার জন্য ব্যবহৃত হয়।
সিগনেচার:
<T> T queryForObject(String sql, Class<T> requiredType)
<T> T queryForObject(String sql, Object[] args, Class<T> requiredType)
<T> T queryForObject(String sql, Object[] args, RowMapper<T> rowMapper)
উদাহরণ ১: সিঙ্গেল ভ্যালু রিটার্ন করা
একটি টেবিল থেকে employee_count রিটার্ন করা:
String sql = "SELECT COUNT(*) FROM employees";
int count = jdbcTemplate.queryForObject(sql, Integer.class);
System.out.println("Total Employees: " + count);
উদাহরণ ২: অবজেক্ট রিটার্ন করা
একটি নির্দিষ্ট আইডি দিয়ে Employee অবজেক্ট রিটার্ন করা:
String sql = "SELECT id, name, department FROM employees WHERE id = ?";
Employee employee = jdbcTemplate.queryForObject(
sql,
new Object[] {1},
(rs, rowNum) -> {
Employee emp = new Employee();
emp.setId(rs.getInt("id"));
emp.setName(rs.getString("name"));
emp.setDepartment(rs.getString("department"));
return emp;
}
);
System.out.println("Employee Name: " + employee.getName());
2. query()
query() মেথড ব্যবহার করা হয় যখন ডাটাবেস থেকে একাধিক রেকর্ড (multiple rows) রিটার্ন করতে হয়। এটি সাধারণত একটি লিস্ট বা কলেকশন ফর্মে রিটার্ন করে।
সিগনেচার:
<T> List<T> query(String sql, RowMapper<T> rowMapper)
<T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper)
<T> List<T> query(String sql, ResultSetExtractor<T> resultSetExtractor)
উদাহরণ ১: একাধিক রেকর্ড রিটার্ন করা
employees টেবিল থেকে সব এমপ্লয়ি রেকর্ড ফেচ করা:
String sql = "SELECT id, name, department FROM employees";
List<Employee> employees = jdbcTemplate.query(
sql,
(rs, rowNum) -> {
Employee emp = new Employee();
emp.setId(rs.getInt("id"));
emp.setName(rs.getString("name"));
emp.setDepartment(rs.getString("department"));
return emp;
}
);
employees.forEach(emp -> System.out.println("Employee Name: " + emp.getName()));
উদাহরণ ২: ফিল্টার করা রেকর্ড রিটার্ন করা
নির্দিষ্ট ডিপার্টমেন্টের এমপ্লয়ি লিস্ট রিটার্ন করা:
String sql = "SELECT id, name, department FROM employees WHERE department = ?";
List<Employee> employees = jdbcTemplate.query(
sql,
new Object[] {"HR"},
(rs, rowNum) -> {
Employee emp = new Employee();
emp.setId(rs.getInt("id"));
emp.setName(rs.getString("name"));
emp.setDepartment(rs.getString("department"));
return emp;
}
);
employees.forEach(emp -> System.out.println("Employee Name: " + emp.getName()));
queryForObject() বনাম query(): প্রধান পার্থক্য
| প্যারামিটার | queryForObject() | query() |
|---|---|---|
| ব্যবহার ক্ষেত্র | একক রেকর্ড বা সিঙ্গেল রাউ রিটার্ন করার জন্য। | একাধিক রেকর্ড বা রাউ রিটার্ন করার জন্য। |
| রিটার্ন টাইপ | একটি অবজেক্ট রিটার্ন করে। | একটি লিস্ট বা কলেকশন রিটার্ন করে। |
| ব্যতিক্রম | যদি কোনো রেকর্ড পাওয়া না যায়, EmptyResultDataAccessException থ্রো করে। | রেকর্ড না পেলে খালি লিস্ট রিটার্ন করে। |
কোনটি ব্যবহার করবেন?
- queryForObject():
- যখন আপনি নিশ্চিত যে শুধুমাত্র একটি রেকর্ড রিটার্ন হবে।
- একক ভ্যালু বা একক অবজেক্ট পেতে।
- query():
- যখন আপনি একাধিক রেকর্ড রিটার্ন করতে চান।
- বড় ডাটাসেট থেকে ফিল্টার করা রেকর্ড পেতে।
Spring JDBC-র queryForObject() এবং query() মেথড ডাটাবেস অপারেশনগুলোকে সহজ এবং কার্যকর করে তোলে। এগুলো ডেভেলপারের কাজের সময় এবং প্রচেষ্টা উভয়ই বাঁচায়।
Spring JDBC ডেটাবেস থেকে ডেটা রিট্রাইভ করার জন্য RowMapper এবং ResultSetExtractor ইন্টারফেস সরবরাহ করে। এদের মাধ্যমে ডেটাকে জাভার অবজেক্টে ম্যাপ করা সহজ হয় এবং কোড আরও পরিষ্কার এবং সংগঠিত হয়।
1. RowMapper:
RowMapper ইন্টারফেস ব্যবহার করে প্রতিটি ডেটাবেস রেকর্ডকে একটি অবজেক্টে ম্যাপ করা হয়। এটি প্রতিটি রো প্রসেস করার জন্য একটি mapRow() মেথড সরবরাহ করে।
Syntax:
public interface RowMapper<T> {
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
উদাহরণ: RowMapper এর ব্যবহার
ধরা যাক, আমাদের একটি Employee ক্লাস এবং employees টেবিল আছে।
Employee.java
public class Employee {
private int id;
private String name;
private String department;
// Getters and Setters
}
ডেটা রিট্রাইভ করার উদাহরণ:
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
public class RowMapperExample {
public static void main(String[] args) {
// DataSource সেটআপ
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("password");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// SQL Query
String query = "SELECT * FROM employees";
// RowMapper Implementation
List<Employee> employees = jdbcTemplate.query(query, new RowMapper<Employee>() {
@Override
public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getInt("id"));
employee.setName(rs.getString("name"));
employee.setDepartment(rs.getString("department"));
return employee;
}
});
// Output Results
for (Employee emp : employees) {
System.out.println("ID: " + emp.getId() + ", Name: " + emp.getName() + ", Department: " + emp.getDepartment());
}
}
}
Lambda Expression ব্যবহার:
List<Employee> employees = jdbcTemplate.query(query, (rs, rowNum) -> {
Employee employee = new Employee();
employee.setId(rs.getInt("id"));
employee.setName(rs.getString("name"));
employee.setDepartment(rs.getString("department"));
return employee;
});
2. ResultSetExtractor:
ResultSetExtractor ইন্টারফেস ব্যবহার করে পুরো ResultSet প্রসেস করা হয়। এটি বড় ডেটাসেট বা কাস্টম লজিক প্রয়োগের জন্য উপযোগী।
Syntax:
public interface ResultSetExtractor<T> {
T extractData(ResultSet rs) throws SQLException, DataAccessException;
}
উদাহরণ: ResultSetExtractor এর ব্যবহার
ডেটা রিট্রাইভ করার উদাহরণ:
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class ResultSetExtractorExample {
public static void main(String[] args) {
// DataSource সেটআপ
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("password");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// SQL Query
String query = "SELECT * FROM employees";
// ResultSetExtractor Implementation
List<Employee> employees = jdbcTemplate.query(query, new ResultSetExtractor<List<Employee>>() {
@Override
public List<Employee> extractData(ResultSet rs) throws SQLException {
List<Employee> employeeList = new ArrayList<>();
while (rs.next()) {
Employee employee = new Employee();
employee.setId(rs.getInt("id"));
employee.setName(rs.getString("name"));
employee.setDepartment(rs.getString("department"));
employeeList.add(employee);
}
return employeeList;
}
});
// Output Results
for (Employee emp : employees) {
System.out.println("ID: " + emp.getId() + ", Name: " + emp.getName() + ", Department: " + emp.getDepartment());
}
}
}
RowMapper এবং ResultSetExtractor এর মধ্যে পার্থক্য:
| বৈশিষ্ট্য | RowMapper | ResultSetExtractor |
|---|---|---|
| প্রক্রিয়াকরণ পদ্ধতি | প্রতিটি রো প্রসেস করে। | পুরো ResultSet প্রসেস করে। |
| উপযোগিতা | সাধারণ ক্ষেত্রে ব্যবহৃত হয়। | বড় বা জটিল ডেটাসেটের জন্য ব্যবহৃত। |
| সহজতা | সহজ এবং ক্লিন কোড তৈরি করে। | কাস্টম লজিক প্রয়োগের জন্য কার্যকর। |
কোনটি ব্যবহার করবেন?
RowMapper:
যখন প্রতিটি রো সহজভাবে একটি অবজেক্টে ম্যাপ করতে হবে।
উদাহরণ: একটিSELECTস্টেটমেন্টের ফলাফল ম্যাপ করা।ResultSetExtractor:
যখন ডেটাবেসের রেকর্ড প্রসেস করতে কাস্টম লজিক প্রয়োজন, যেমন: একাধিক টেবিলের ডেটা ম্যাপ করা বা জটিল ডেটাসেট প্রসেস করা।
উপসংহার:
Spring JDBC-তে RowMapper এবং ResultSetExtractor ডেটা ম্যাপিংয়ের জন্য শক্তিশালী টুল। আপনার প্রয়োজন অনুযায়ী এই দুটি ইন্টারফেস ব্যবহার করে সহজে ডেটাবেস থেকে ডেটা রিট্রাইভ এবং প্রসেস করা যায়।
স্প্রিং জেডিবিসি (Spring JDBC) তে JdbcTemplate এবং NamedParameterJdbcTemplate ব্যবহার করে ডাটাবেসে বিভিন্ন ধরনের কোয়ারি চালানো যায়। নিচে উদাহরণসহ বিভিন্ন কোয়ারি মেথডগুলোর ব্যবহার দেখানো হলো:
১. queryForObject()
এই মেথডটি একটি সিঙ্গেল রেকর্ড (একটি রো) রিটার্ন করে। এটি সাধারণত যেখানে সুনির্দিষ্ট একটি রেকর্ড রিটার্ন করার প্রয়োজন হয় সেখানে ব্যবহার করা হয়।
উদাহরণ:
String sql = "SELECT name FROM students WHERE id = ?";
String name = jdbcTemplate.queryForObject(sql, new Object[]{1}, String.class);
System.out.println("Student Name: " + name);
২. query()
এই মেথডটি এক বা একাধিক রেকর্ড (মাল্টিপল রো) রিটার্ন করার জন্য ব্যবহার করা হয়। এটি RowMapper ব্যবহার করে ডাটাকে মডেল অবজেক্টে ম্যাপ করে।
উদাহরণ:
String sql = "SELECT id, name, age FROM students";
List<Student> students = jdbcTemplate.query(sql, (rs, rowNum) -> {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
});
students.forEach(student ->
System.out.println("ID: " + student.getId() + ", Name: " + student.getName() + ", Age: " + student.getAge()));
৩. queryForList()
ডাটাবেস থেকে একটি লিস্ট অবজেক্ট রিটার্ন করে। এটি সাধারণত সরাসরি লিস্ট হিসেবে রেজাল্ট পেতে ব্যবহৃত হয়।
উদাহরণ:
String sql = "SELECT name FROM students";
List<String> names = jdbcTemplate.queryForList(sql, String.class);
names.forEach(System.out::println);
৪. queryForMap()
এই মেথডটি একটি সিঙ্গেল রেকর্ড (একটি রো) কে একটি Map হিসাবে রিটার্ন করে, যেখানে কলামের নামগুলো কী এবং তাদের মানগুলো ভ্যালু হিসেবে থাকে।
উদাহরণ:
String sql = "SELECT id, name, age FROM students WHERE id = ?";
Map<String, Object> student = jdbcTemplate.queryForMap(sql, 1);
System.out.println("ID: " + student.get("id"));
System.out.println("Name: " + student.get("name"));
System.out.println("Age: " + student.get("age"));
৫. update()
ডাটাবেসে ডাটা INSERT, UPDATE বা DELETE করার জন্য ব্যবহার করা হয়।
উদাহরণ:
Insert Operation:
String sql = "INSERT INTO students (name, age) VALUES (?, ?)";
int result = jdbcTemplate.update(sql, "John Doe", 22);
if (result > 0) {
System.out.println("A new student has been inserted.");
}
Update Operation:
String sql = "UPDATE students SET age = ? WHERE id = ?";
int result = jdbcTemplate.update(sql, 25, 1);
if (result > 0) {
System.out.println("Student's age has been updated.");
}
Delete Operation:
String sql = "DELETE FROM students WHERE id = ?";
int result = jdbcTemplate.update(sql, 1);
if (result > 0) {
System.out.println("A student has been deleted.");
}
৬. Batch Update
একাধিক রেকর্ড একসঙ্গে আপডেট করার জন্য ব্যবহার করা হয়। এটি পারফরম্যান্স উন্নত করতে সহায়ক।
উদাহরণ:
String sql = "INSERT INTO students (name, age) VALUES (?, ?)";
List<Object[]> batchArgs = Arrays.asList(
new Object[]{"Alice", 20},
new Object[]{"Bob", 22},
new Object[]{"Charlie", 23}
);
int[] results = jdbcTemplate.batchUpdate(sql, batchArgs);
System.out.println("Batch Update Completed: " + Arrays.toString(results));
৭. NamedParameterJdbcTemplate ব্যবহার
নামযুক্ত প্যারামিটার দিয়ে কোয়ারি চালানোর জন্য এটি ব্যবহার করা হয়।
উদাহরণ:
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
// Insert Operation
String sql = "INSERT INTO students (name, age) VALUES (:name, :age)";
Map<String, Object> params = new HashMap<>();
params.put("name", "David");
params.put("age", 24);
int result = namedParameterJdbcTemplate.update(sql, params);
if (result > 0) {
System.out.println("A new student has been inserted using NamedParameterJdbcTemplate.");
}
// Select Operation
String selectSql = "SELECT id, name, age FROM students WHERE age > :age";
Map<String, Object> selectParams = new HashMap<>();
selectParams.put("age", 20);
List<Student> students = namedParameterJdbcTemplate.query(selectSql, selectParams, (rs, rowNum) -> {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
});
students.forEach(student ->
System.out.println("ID: " + student.getId() + ", Name: " + student.getName() + ", Age: " + student.getAge()));
সংক্ষেপে:
| মেথড | ব্যবহার | রিটার্ন টাইপ |
|---|---|---|
queryForObject | একটি সিঙ্গেল রেকর্ড ফিল্ড রিটার্ন করতে | একটি সিঙ্গেল ভ্যালু বা অবজেক্ট |
query | মাল্টিপল রেকর্ড ফিল্ড রিটার্ন করতে | একটি লিস্ট (RowMapper সহ) |
queryForList | মাল্টিপল রেকর্ড সরাসরি লিস্ট রিটার্ন করতে | লিস্ট |
queryForMap | একটি রেকর্ডকে ম্যাপ রিটার্ন করতে | Map (Key: Column Name, Value: Value) |
update | ডাটাবেসে ডাটা আপডেট/ইনসার্ট/ডিলিট করতে | int (affected rows count) |
batchUpdate | একাধিক রেকর্ড আপডেট করতে | int[] (প্রতিটি অপারেশনের ফলাফল) |
Spring JDBC এর এই মেথডগুলো ডেভেলপারদের ডাটাবেস অপারেশন দ্রুত এবং সহজে করতে সহায়তা করে।
Read more